package com.stylefeng.guns.rest.modular.order;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.baomidou.mybatisplus.plugins.Page;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.stylefeng.guns.api.order.OrderServiceApi;
import com.stylefeng.guns.api.order.vo.OrderVo;
import com.stylefeng.guns.api.pay.AlipayServiceApi;
import com.stylefeng.guns.api.pay.vo.AlipayInfoVo;
import com.stylefeng.guns.api.pay.vo.AlipayResultVo;
import com.stylefeng.guns.api.util.TokenBucket;
import com.stylefeng.guns.rest.common.CurrentUser;
import com.stylefeng.guns.rest.modular.vo.ResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName OrderController
 * @Description TODO
 * @Author zhaoluowei
 * @Date 2019/9/18  17:57
 * @Version 1.0
 * <p>
 * <p>
 * 此接口不能忽略 需要用户必须登录
 */
@RestController
@RequestMapping(value = "/order")
@Slf4j
public class OrderController {


    @Reference(interfaceClass = OrderServiceApi.class, check = false, group = "order2018")
    private OrderServiceApi orderServiceApi;


    @Reference(interfaceClass = OrderServiceApi.class, check = false, group = "order2017")
    private OrderServiceApi orderServiceApi2017;

    @Reference(interfaceClass = AlipayServiceApi.class, check = false)
    private AlipayServiceApi alipayServiceApi;


    private static TokenBucket tokenBucket = new TokenBucket();

    private static final String img_pre = "http://img.meetingshop.cn/";

    //熔断的方法
    public ResponseVo error(Integer fieldId, String soldSeats, String seatsName) {
        return ResponseVo.serviceFail("抱歉，下单的人太多了，请稍后重试");
    }


    /**
     * 买票接口 需要验证 当前用户是否登录
     * 有个接口是给分布式事务使用的
     *
     * @return
     */
    @HystrixCommand(fallbackMethod = "error", commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value
                    = "4000"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
    }, threadPoolProperties = {
            @HystrixProperty(name = "coreSize", value = "1"),
            @HystrixProperty(name = "maxQueueSize", value = "10"),
            @HystrixProperty(name = "keepAliveTimeMinutes", value = "1000"),
            @HystrixProperty(name = "queueSizeRejectionThreshold", value = "8"),
            @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
            @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1500")
    })
    @PostMapping(value = "/buyTickets")
    public ResponseVo buyTickets(Integer fieldId, String soldSeats, String seatsName) {

        try {
            log.info("请求参数 --> fieldId " + fieldId + "  soldSeats --> " + soldSeats + "  seatsName --> " + seatsName);
            if (tokenBucket.getToken()) {
                //永远不要相信前端传过来的东西。
                //验证售出的票 是否为真
                boolean trueSeats = orderServiceApi.isTrueSeats(fieldId + "", soldSeats);
                //去已经销售的订单里面 进行查询有没有这些作为(在购票页面 要把已售和未售一起返回前台)
                boolean isNotSold = orderServiceApi.isNotSoldSeats(fieldId + "", soldSeats);
                log.info(" trueSeats --> " + trueSeats + " isNotSold --> " + isNotSold);


                if (trueSeats && isNotSold) {
                    //创建订单信息 要获取登录人的信息
                    String userId = CurrentUser.getCurrentUserInfoModer();
                    log.info("获取当前登录人的id --> userId " + userId);

                    if (userId == null || userId.trim().length() == 0) {
                        return ResponseVo.serviceFail("用户未登录");
                    }

                    OrderVo orderVo = orderServiceApi.saveOrderInfo(fieldId, soldSeats, seatsName, Integer.parseInt(userId));

                    if (orderVo == null) {
                        //也是 创建失败
                        log.error("购票业务异常 --> " + orderVo);
                        return ResponseVo.serviceFail("购票业务异常");
                    } else {
                        return ResponseVo.success(orderVo);
                    }
                } else {

                    return ResponseVo.serviceFail("订单中的座位编号有问题");
                }
            } else {
                return ResponseVo.serviceFail("购票人数过多，请稍后再试");
            }

        } catch (Exception e) {
            log.error("购票业务异常 --> " + e.getMessage());
            e.printStackTrace();
            return ResponseVo.serviceFail("购票业务异常");
        }
    }

    /**
     * 根据用户信息  查订单
     *
     * @return
     */
    @PostMapping(value = "/getOrderInfo")
    public ResponseVo getOrderInfo(@RequestParam(name = "nowPage", required = false, defaultValue = "1") Integer nowPage,
                                   @RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize) {

        //获取当前登录人的信息
        String userId = CurrentUser.getCurrentUserInfoModer();
        log.info("获取当前登录人的id --> userId " + userId);
        //查询 和当前登录人相关的 订单详情
        if (userId != null || userId.trim().length() > 0) {
            Page<OrderVo> page = new Page<>(nowPage, pageSize);
            Page<OrderVo> orderVoPage1 = orderServiceApi.getOrderByUserId(Integer.parseInt(userId), page);
            log.info("返回给前端集合 --> orderVoPage1 " + orderVoPage1.getRecords());


            Page<OrderVo> orderVoPage12017 = orderServiceApi2017.getOrderByUserId(Integer.parseInt(userId), page);
            log.info("返回给前端集合 --> orderVoPage12017 " + orderVoPage12017.getRecords());


            //合并结果
            //计算总条数
            int total = (int) (orderVoPage1.getTotal() + orderVoPage12017.getTotal());
            //总数据合并
            List<OrderVo> orderVos = new ArrayList<>();
            orderVos.clear();
            orderVos.addAll(orderVoPage1.getRecords());
            orderVos.addAll(orderVoPage12017.getRecords());


            // return ResponseVo.success((int) orderVoPage1.getTotal(), nowPage, "", orderVoPage1.getRecords());
            return ResponseVo.success(total, nowPage, "", orderVos);
        } else {

            return ResponseVo.serviceFail("用户未登录");
        }

    }

    @PostMapping(value = "/getPayInfo")
    public ResponseVo getPayInfo(@RequestParam("orderId") String orderId) {
        String userId = CurrentUser.getCurrentUserInfoModer();
        log.info(" 获取支付信息接口  获取当前登录人的id --> userId " + userId);
        if (userId == null || userId.trim().length() == 0) {
            return ResponseVo.serviceFail("用户未登录");
        }

        //订单二维码的 返回结果
        AlipayInfoVo alipayInfoVo = alipayServiceApi.getORCode(orderId);

        return ResponseVo.success(img_pre, alipayInfoVo);
    }


    @PostMapping(value = "/getPayResult")
    public ResponseVo getPayResult(@RequestParam("orderId") String orderId,
                                   @RequestParam("tryNums") Integer tryNums) {

        String userId = CurrentUser.getCurrentUserInfoModer();
        log.info(" 获取支付接口接口  获取当前登录人的id --> userId " + userId);
        if (userId == null || userId.trim().length() == 0) {
            return ResponseVo.serviceFail("用户未登录");
        }

        //讲当前登录人的信息传递给 后端
        RpcContext.getContext().setAttachment("userId", userId);


        if (tryNums >= 4) {
            return ResponseVo.serviceFail("订单支付失败,请稍后再试");
        } else {
            AlipayResultVo resultVo = alipayServiceApi.getOrderPayStatus(orderId);
            return ResponseVo.success(resultVo);
        }
    }


}
